This invention relates to debugging an application software process. In particular it relates to generating a stateful copy of application process objects at runtime.
Identification and correction of errors in software is an important part of the software development process. An error can manifest in many ways including an incorrect data value, an incorrect flow of application logic or a failure of all or part of a software application. More subtly, errors can result in synchronization and timing problems in the execution of an application which may be difficult or impossible to reproduce. Techniques can be employed at development time to diagnose and resolve errors.
One diagnosis technique involves embedding tracing instructions into a software application to provide trace information at runtime relating to the status and flow of the application. For example, trace information can be generated as textual strings or numerical identifiers providing contents of application data structures. The inclusion of tracing instructions in a software application increases the overall size of the application and affects the runtime performance of the application because resources are consumed at runtime in order to generate trace information. Tracing instructions are therefore not suitable for a production software application where application size and performance are paramount. Furthermore, the continued generation of diagnosis trace information is dependent upon continued and stable operation of the application at runtime. If the application becomes unstable (for example, if a synchronization deadlock occurs or the application fails completely) the generation of trace information will cease. Furthermore, the trace information generated by the application at runtime are determined by the tracing instructions embedded in the application at development time. A developer is not easily able to include additional tracing instructions or remove unnecessary tracing instructions without recompiling the application or implementing complex tracing configuration logic which would itself introduce a large performance overhead.
Another technique for the diagnosis of software errors involves the use of a software debugger. A debugger is a software program for locating operational errors in a software application. For example, a debugger enables a developer to step through a malfunctioning portion of a software application to examine data and check operational conditions. A debugger can be used with an application at runtime (known in the art as the process of debugging). For example, FIG. 1 illustrates an arrangement of a computer system 100 for diagnosing errors in an application process 104 at runtime in the prior art. The application process 104 is an object oriented Java application at runtime residing in a memory 106 of the computer system 100 (Java is a registered trademark of Sun Microsystems, Inc.). The application process 104 includes an application heap 108 which is a reserved area of memory for the storage of application data at runtime. The application heap 108 includes application object 1082. Application object 1082 is a Java object which is an instance of a Java class. Application object 1082 includes an identifier of the Java class of which it is an instance. The application process 104 also includes debug logic which provides debug events for inter operation with a debugger. For example, the application process 104 can be executed with the “-Xdebug” Java runtime option to provide this debug logic. Application class files 110 are Java class files including Java bytecodes defining the object oriented classes for the application process 106. In particular, application class files 110 include a class definition corresponding to the application object 1082. The Java bytecodes which comprise the application class files 110 define both data (attributes) and functionality (software methods) of the class corresponding to the application object 1082.
A debugger is represented as debug process 102 which also resides in the memory 106 of the computer system 100. For example, the debug process 102 is the Java debugger “jdb”. The debug process 102 can alternatively reside in a memory of a remote computer system. The debug process 102 and the application process 104 are separate processes which can operate on the computer system 100 independently of each other. The debug process 102 is described as an “out of process” debugger since it operates outside the application process 104. The debug process 102 is communicatively connected to application process 104 via communications link 112. An example of communications link 112 is a sockets connection. The debug process 102 receives debug events from, and sends debug commands to, the application process 104. Alternatively, the communications link 112 can be formed by attaching the debug process 102 to the application process 104 using the UNIX “attach” command, as disclosed on the worldwide web at “www.mathstat.dal.ca/˜kassiem/HPC/commands/attach.html” (UNIX is a registered trademark of The Open Group). As a further alternative, the “Attach” method of the “Process” object in the Visual Studio Debugger Object Model distributed by the Microsoft Corporation provides equivalent functionality as disclosed on the worldwide web at “msdn.microsoft.com/library/default.asp?url=/library/en-us/vsdebugext/html/vxlrfenvdteprocessattac h.asp” (Visual Studio is a registered trademark of Microsoft Corporation). An advantage of using the “attach” command or the “Attach” method to form communications link 112 is that the debug process 102 becomes functionally attached to the application process 104 and the debug process 102 is able to access the application heap 108.
In these ways the debug process 102 is able to interact with the application process 104. A software developer is able to use the debug process 102 to step through the logic of the application process 104 and interrogate values of objects stored in the application heap 108 at runtime. However, the use of a debug process such as that described above has many disadvantages that render it impractical for a production application. In particular, the requirement that the application process 104 include debug logic for providing debug events (such as through the “-Xdebug” Java runtime option) results in the application process 104 occupying more of the memory 106 of the computer system 100, and a reduced runtime performance in terms of speed of execution. In a production system, resource efficiency and runtime performance can be paramount characteristics of an application process. Furthermore, the need for the application process 104 to include debug logic can prevent the use of runtime optimizations in the application process 104, such as the use of a “just-in-time” compiler (JIT).
Also the inclusion of additional debug logic in the application process 104 will change the timing characteristics of the application process 104 during execution. For example, application functionality of the application process 104 may execute at different points in time during execution of the application process 104 depending upon the inclusion of debug logic. This results from the additional time spent executing debug logic which has a knock-on effect on the particular time application functionality is executed. Consequently, timing sensitive errors such as synchronization locks and deadlocks may manifest differently in an application process executed with the “-Xdebug” option, and these errors may not be reproducible when the “-Xdebug” option is selected.
Additionally the effectiveness of a debug process is reliant upon the integrity and stability of the application process 104 at runtime as the application process 104 must execute debug logic and generate debug events. Thus the application process 104 must be stable enough to provide the required debug events for cooperation with a Java debugger. Where application stability and integrity cannot be assured (such as when an error is present) then debug events may not be generated so preventing effective debugging.